package cn.tedu.websocket.demo.server;

import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * WebSocket服务端
 * @ServerEndpoint 注解的类，都会被扫描到
 * 会创建一个ws的端点,可以接受前端的请求 建立ws连接
 */
@Slf4j
@Component
@ServerEndpoint("/ws/server/{userId}")
public class WebSocketServer {


    /**
     * 用户id 和 session的映射关系
     * Key 用户id
     * Value session
     */
    private static Map<Integer,Session> sessions = new HashMap<>();

    /**
     * 建立连接
     *  connectComplete mqttConsumer 连接成功
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") Integer userId) {
        log.info("建立连接,sessionId:{},用户id:{}",session.getId(),userId);
        //用户建立连接成功后,欢迎招呼
        String message = "欢迎您访问，你好:" + userId;
        try {
            //发送消息
            session.getBasicRemote().sendText(message);
        } catch (IOException e) {
           log.error("发送消息失败",e);
        }
        //添加用户id和session的映射关系
        sessions.put(userId,session);
    }

    @OnClose
    public void onClose(Session session,@PathParam("userId") Integer userId) {
        log.info("关闭连接,sessionId:{}",session.getId());
        //关闭连接后,移除用户id和session的映射关系
        sessions.remove(userId);
    }

    @OnError
    public void onError(Throwable error,Session session) {
        log.error("错误,sessionId:{}", session.getId(),error);
    }

    /**
     * messageArrived mqttConsumer 消息达到
     * 客户端发送的消息到达了 服务端
     * @param message
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("收到消息: {},sessionId:{}", message,session.getId());
        String replyMessage = "您好,收到消息: " + message;
        try {
            session.getBasicRemote().sendText(replyMessage);
        } catch (IOException e) {
            log.error("发送消息失败",e);
        }
    }

    /**
     * 发送消息给指定用户
     * @param userId
     * @param message
     */
    public void sendMsg2User(Integer userId, String message) {
        //获取指定用户的session
        Session session = sessions.get(userId);
        if (session != null) {
            //session 不为null 说明用户在线
            try {
                //发送消息
                session.getBasicRemote().sendText(message);
            } catch (IOException e) {
                log.error("发送消息失败",e);
            }
        }else {
            log.info("用户:{} 不在线",userId);
        }
    }
}
